package com.bruce.starts.demo.commonerror.reflection;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author luotuan
 * @Description
 * @create 2021-05-12 16:03
 **/
@Slf4j
public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        ReflectionDemo reflectionDemo = new ReflectionDemo();
        //reflectionDemo.wrong();
        //reflectionDemo.right();
        reflectionDemo.test1();
    }
    private void age(int age) {
        log.info("int age = {}", age);
    }

    private void age(Integer age) {
        log.info("Integer age = {}", age);
    }

    private void wrong() throws Exception {
        getClass().getDeclaredMethod("age",Integer.TYPE).invoke(this,27);
    }

    private void right() throws Exception {
        getClass().getDeclaredMethod("age",Integer.class).invoke(this,27);
    }
    private void test1(){
        child child = new child();
        Arrays.stream(child.getClass().getDeclaredMethods())
                .filter(method -> "setValue".equalsIgnoreCase(method.getName()) && !method.isBridge())
                .findFirst().ifPresent(method -> {
            try {
                method.invoke(child,"test");
            }
            catch (Exception e) {
            }
        });
        System.out.println(child.toString());
    }
}
class Parent<T>{
    private T value;
    AtomicInteger updateCount = new AtomicInteger();
    @Override
    public String toString() {
        return String.format("value: %s updateCount: %d", value, updateCount.get());
    }
    public void setValue(T value){
        System.out.println("Parent.setValue called");
        this.value = value;
        updateCount.incrementAndGet();
    }
}
class child extends Parent<String>{
    @Override
    public void setValue(String value) {
        System.out.println("Child1.setValue called");
        super.setValue(value);
    }
}
